package business.global.pk.zjh;

import java.util.*;

import business.global.room.base.AbsRoomPos;
import business.global.room.base.AbsRoomPosMgr;
import business.global.room.base.DissolveRoom;
import business.global.room.pk.PockerRoom;
import business.zjh.c2s.cclass.ZJHRoomSetInfo;
import business.zjh.c2s.cclass.ZJH_define;
import business.zjh.c2s.iclass.*;
import cenum.*;
import cenum.room.GameRoomConfigEnum;
import cenum.room.RoomState;
import cenum.room.CKickOutType;

import com.google.gson.Gson;

import business.global.room.RoomRecordMgr;
import jsproto.c2s.cclass.BaseSendMsg;
import jsproto.c2s.cclass.pk.PKRoom_Record;
import jsproto.c2s.cclass.pk.PKRoom_RecordPosInfo;
import jsproto.c2s.cclass.room.BaseResults;
import jsproto.c2s.cclass.room.BaseRoomConfigure;
import jsproto.c2s.cclass.room.GetRoomInfo;
import jsproto.c2s.cclass.room.RoomPosInfo;
import jsproto.c2s.cclass.union.UnionDefine;
import jsproto.c2s.iclass.S_GetRoomInfo;
import jsproto.c2s.iclass.room.SBase_Dissolve;
import jsproto.c2s.iclass.room.SBase_PosLeave;
import org.apache.commons.collections.CollectionUtils;

public class ZJHRoom extends PockerRoom {
    public static final int[] qipaitime = {16000,31000,61000};
//    public ZJHRoom_Cfg cfg; //创建配置
    public List<ZJHRoomSet> historySet = new ArrayList<ZJHRoomSet>(); // 历史局
    public ZJHRoomSet curSet = null; // 当前局
    public final int maxCardCount = 3;
    private int callbacker = -1; //庄家备份 -1:标识没有庄家
    private ZJHConfigMgr configMgr = new ZJHConfigMgr();
    private ArrayList<Long>  m_XiPaiPidList = new ArrayList<Long>(); //洗牌pid 大于0标识洗牌玩家pid
    private int playingCount;
    public CZJH_CreateRoom roomCfg; //创建配置
//    public final int maxCardCount = 5;
    public final int endPointList[] = {2, 4, 8};
//    public final int backerPointList[] = {0, 100, 150, 200};
//    private int callbacker = -1; //庄家备份 -1:标识没有庄家
//    private ZJHConfigMgr configMgr = new ZJHConfigMgr();


    protected ZJHRoom(BaseRoomConfigure<CZJH_CreateRoom> baseRoomConfigure, String roomKey, long ownerID) {
        super(baseRoomConfigure, roomKey, ownerID);
        initShareBaseCreateRoom(CZJH_CreateRoom.class, baseRoomConfigure);
        this.roomCfg = (CZJH_CreateRoom) baseRoomConfigure.getBaseCreateRoom();
    }

    /**
     * 房间内每个位置信息 管理器
     */
    @Override
    public AbsRoomPosMgr initRoomPosMgr() {
        return new ZJHRoomPosMgr(this);
    }

    @Override
    public void initCreatePos() {
        if (this.getOwnerID() <= 0L) {
            return;
        }
        // 进入房间
        this.enterRoomVisitor(this.getOwnerID(), this.getRoomPosMgr().getPlayerNum(), false,null);
    }

    /**
     * 获取房间配置
     *
     * @return
     */
    public CZJH_CreateRoom getRoomCfg() {
        if (this.roomCfg == null) {
            initShareBaseCreateRoom(CZJH_CreateRoom.class, getBaseRoomConfigure());
            return (CZJH_CreateRoom) getBaseRoomConfigure().getBaseCreateRoom();
        }
        return this.roomCfg;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T getCfg() {
        return (T) getRoomCfg();
    }

    @Override
    public String dataJsonCfg() {
        // 获取房间配置
        return new Gson().toJson(this.getRoomCfg());
    }

    /**
     * 清除记录。
     */
    @Override
    public void clearEndRoom() {
        super.clear();
        this.roomCfg = null;
    }


    @Override
    public boolean getCurSetUpdate(int sec) {
        return getCurSet().update(sec);
    }


    @Override
    public void startNewSet() {
        this.setCurSetID(this.getCurSetID() + 1);
        this.createSet();
        // 每个位置，清空准备状态
        this.getRoomPosMgr().clearGameReady();
    }

    //创建set
    public void createSet() {
        Map<Integer, Integer> winControlMap = new HashMap<>();
        if (null != this.getCurSet()) {
            winControlMap = ((ZJHRoomSet) this.getCurSet()).winControlMap;
            this.getCurSet().clear();
            this.setCurSet(null);
        }
        this.setCurSet(new ZJHRoomSet(this, winControlMap));
        this.getRoomTyepImpl().roomSetIDChange();
    }

    @Override
    public void setEndRoom() {
        if (null != this.getCurSet()) {
            if (getHistorySet().size() > 0) {
                // 增加房局记录
                RoomRecordMgr.getInstance().add(this);
                ((ZJHRoomSet) this.getCurSet()).getRoomPlayBack().playBack2All(SZJH_RoomEnd.make(this.getPKRoomRecordInfo()));
                refererReceiveList();
            }
        }
    }

    /*
     * 主动离开房间的其他条件 条件不满足不退出
     * */
    @Override
    public boolean exitRoomOtherCondition(long pid) {
        // 游戏已经开始，不能自由离开 防止一人加入一人退出时bug
        if (this.getCurSet() != null && this.getCurSet().getSetID() == 0 && !RoomState.Init.equals(this.getRoomState())) {
            return false;
        }
        // 玩家玩过游戏就不能离开
        ZJHRoomPos pos = (ZJHRoomPos) this.getRoomPosMgr().getPosByPid(pid);
        if (pos != null && pos.isPlayTheGame()) {
            return false;
        }
        return true;
    }

    /**
     * 构建房间回放返回给客户端
     *
     * @return 通知结构体
     */
    public PKRoom_Record getPKRoomRecordInfo() {
        PKRoom_Record pkRoom_record = new PKRoom_Record();
        pkRoom_record.setCnt = this.getHistorySetSize();
        pkRoom_record.recordPosInfosList = this.getRecordPosInfoList();
        pkRoom_record.roomID = this.getRoomID();
        pkRoom_record.endSec = this.getGameRoomBO().getEndTime();
        return pkRoom_record;
    }


    //获取最大玩家数
    public int getMaxPlayerNum() {
        return ShareDefine.MAXPLAYERNUM_ZJH;
    }

    //获取庄家
    public int getCallBacker() {
        return this.callbacker;
    }

    //设置庄家
    public void setCallBacker(int callBacker) {
        this.callbacker = callBacker;
    }

    @Override
    protected List<PKRoom_RecordPosInfo> getRecordPosInfoList() {
        List<PKRoom_RecordPosInfo> list = new ArrayList<>();
        for (BaseResults x : this.allRecordPosInfoList.values()){
            list.add((PKRoom_RecordPosInfo)x);
        }
        return list;
    }

    /**
     * 加入房间的其他条件 条件不满足不进入
     */
    @Override
    public boolean enterRoomOtherCondition(long pid) {
        if (this.getRoomCfg().gaojixuanxiang.contains(0) && this.getRoomState() != RoomState.Init) {
            return false;
        }
        return true;
    }

    @Override
    public boolean autoStartGame() {
//        //亲友圈 大联盟2-8人自动开始游戏
//        if (RoomTypeEnum.checkUnionOrClub(this.getRoomTyepImpl().getRoomTypeEnum())) {
//            return true;
//        }
        return true;
    }

    //当前几个人在玩
    public int getPlayingCount() {
        int count = 0;
        if (this.getCurSet() != null) {
            count = ((ZJHRoomSet) this.getCurSet()).getPlayingCount();
        } else {
            count = this.getMaxPlayerNum();
        }
        return count;
    }

    @Override
    public DissolveRoom initDissolveRoom(int posID, int WaitSec) {
        return new ZJHDissolveRoom(this, posID, WaitSec);
    }

    @Override
    public void roomTrusteeship(int pos) {
        ((ZJHRoomSet) this.getCurSet()).roomTrusteeship(pos);
    }

//    @Override
//    public int trusteeshipTimeValue() {
//        return qipaitime[((CZJH_CreateRoom) getBaseRoomConfigure().getBaseCreateRoom()).caozuoshijian];
//    }

    @Override
    public void RobotDeal(int pos) {
        ((ZJHRoomSet) this.getCurSet()).roomTrusteeship(pos);
    }

    /**
     * @return configMgr
     */
    public ZJHConfigMgr getConfigMgr() {
        return configMgr;
    }

    @Override
    public void cancelTrusteeship(AbsRoomPos pos) {
        ((ZJHRoomSet) this.getCurSet()).roomTrusteeship(pos.getPosID());
    }

    @Override
    public boolean isGodCard() {
        // TODO 自动生成的方法存根
        return this.getConfigMgr().isGodCard();
    }

    @Override
    public BaseSendMsg XiPai(long roomID, long pid, ClassType cType) {
        return SZJH_XiPai.make(roomID, pid, cType);
    }

    @Override
    public BaseSendMsg ChatMessage(long pid, String name, String content, ChatType type, long toCId, int quickID) {
        return SZJH_ChatMessage.make(pid, name, content, type, toCId, quickID);
    }

    @Override
    public boolean isCanChangePlayerNum() {
        return this.getBaseRoomConfigure().getBaseCreateRoom().getFangjian().contains(GameRoomConfigEnum.FangJianQieHuanRenShu.ordinal());
    }

    @Override
    public BaseSendMsg ChangePlayerNum(long roomID, int createPos, int endSec, int playerNum) {
        return SZJH_ChangePlayerNum.make(roomID, createPos, endSec, playerNum);
    }

    @Override
    public BaseSendMsg ChangePlayerNumAgree(long roomID, int pos, boolean agreeChange) {
        return SZJH_ChangePlayerNumAgree.make(roomID, pos, agreeChange);
    }

    @Override
    public BaseSendMsg ChangeRoomNum(long roomID, String roomKey, int createType) {
        return SZJH_ChangeRoomNum.make(roomID, roomKey, createType);
    }

    @Override
    public GetRoomInfo getRoomInfo(long pid) {
        S_GetRoomInfo ret = new S_GetRoomInfo();
        // 设置房间公共信息
        this.getBaseRoomInfo(ret);
        if (Objects.nonNull(this.getCurSet())) {
            ret.setSet(this.getCurSet().getNotify_set(pid));
        } else {
            ret.setSet(new ZJHRoomSetInfo());
        }
        return ret;
    }

    /**
     * 神牌消息
     *
     * @param msg
     * @param pid
     */
    @Override
    public boolean godCardMsg(String msg, long pid) {
        return false;
    }

    @Override
    public BaseSendMsg Trusteeship(long roomID, long pid, int pos, boolean trusteeship) {
        return SZJH_Trusteeship.make(roomID, pid, pos, trusteeship);
    }


    @Override
    public BaseSendMsg PosLeave(SBase_PosLeave posLeave) {
        return SZJH_PosLeave.make(posLeave);
    }

    @Override
    public BaseSendMsg LostConnect(long roomID, long pid, boolean isLostCozjhect, boolean isShowLeave) {
        return SZJH_LostConnect.make(roomID, pid, isLostCozjhect, isShowLeave);
    }

    @Override
    public BaseSendMsg PosContinueGame(long roomID, int pos) {
        return SZJH_PosContinueGame.make(roomID, pos);
    }

    @Override
    public BaseSendMsg PosUpdate(long roomID, int pos, RoomPosInfo posInfo, int custom) {
        return SZJH_PosUpdate.make(roomID, pos, -1, posInfo,null,custom);
    }

    @Override
    public BaseSendMsg PosUpdate(long roomID, int pos, RoomPosInfo posInfo, int visit, RoomPosInfo visitInfo, int custom) {
        return SZJH_PosUpdate.make(roomID, pos, visit, posInfo, visitInfo, custom);
    }

    @Override
    public BaseSendMsg VisitUpdate(long roomID, int action, int pos, RoomPosInfo posInfo, int visit, RoomPosInfo visitInfo) {
        return SZJH_VisitUpdate.make(roomID, action, pos, posInfo, visit, visitInfo);
    }

    @Override
    public BaseSendMsg PosReadyChg(long roomID, int pos, boolean isReady) {
        return SZJH_PosReadyChg.make(roomID, pos, isReady);
    }

    @Override
    public BaseSendMsg Dissolve(SBase_Dissolve dissolve) {
        return SZJH_Dissolve.make(dissolve);
    }

    @Override
    public BaseSendMsg StartVoteDissolve(long roomID, int createPos, int endSec) {
        return SZJH_StartVoteDissolve.make(roomID, createPos, endSec);
    }

    @Override
    public BaseSendMsg PosDealVote(long roomID, int pos, boolean agreeDissolve, int endSec) {
        return SZJH_PosDealVote.make(roomID, pos, agreeDissolve);
    }

    @Override
    public BaseSendMsg Voice(long roomID, int pos, String url) {
        return SZJH_Voice.make(roomID, pos, url);
    }

    @Override
    public <T> BaseSendMsg RoomRecord(List<T> records) {
        return SZJH_RoomRecord.make(records);
    }

    @Override
    public int getTimerTime() {
        return 200;
    }

    /**
     * 房主是否需要准备
     *
     * @return
     */
    @Override
    public boolean ownerNeedReady() {
        return true;
    }

    /**
     * 自动准备游戏 玩家加入房间时，自动进行准备。
     */
    @Override
    public boolean autoReadyGame() {
        return getRoomCfg().getKexuanwanfa().contains(ZJH_define.KeXuanWanFa.ZiDong.getType());
    }


    /*
     * 获取顶注
     * **/
    public int getDingZhu(){
        int point =  this.getConfigMgr().getTopPointList().get(this.roomCfg.dingzhu)*this.getConfigMgr().getBottomPointList().get(this.roomCfg.dizhu);
        return point;
    }

    /*
     * 获取轮数上限
     * */
    public int getLunShuShangXian(){
        return this.getConfigMgr().getLunShuShangXian().get(this.roomCfg.lunshushangxian);
    }

    @Override
    public boolean isRulesOfCanNotBelowZero() {
        return true;
    }
    
    /**
     * 踢出盟主标记的玩家
     *
     * @return
     */
    public void killPlayerByMengZhuMark() {
        if (CollectionUtils.isEmpty(this.getRoomPosMgr().getPosList())) {
            // 玩家信息列表没数据
            return;
        }
        boolean isClubOrUnion = RoomTypeEnum.checkUnionOrClub(this.getRoomTypeEnum());
        if(isClubOrUnion){
            List<Long> kickOutList = new ArrayList<>();
            this.getRoomPosMgr().getPosList().stream().forEach(k -> {
                if ( k.getPid() <= 0L) {
                    return;
                }
                if( k.isLeaveNextSet()){
                    kickOutList.add(k.getPid());
                }
            });
            //踢出房间
            kickOutList.stream().forEach(pid -> {
                AbsRoomPos roomPos = this.getRoomPosMgr().getPosByPid(pid);
                roomPos.insertPlayerRoomAloneBO();
                roomPos.updatePlayerRoomAloneBO();
                roomPos.leave(true, this.getOwnerID(), CKickOutType.TIMEOUT);//CKickOutType.TIMEOUT
                this.getRoomPosMgr().setAllEnterTime(0);
            });

            ((ZJHRoomSet)this.getCurSet()).kickOut(kickOutList);
        }
    }
    public int getKillPlayerCount(){
        if (CollectionUtils.isEmpty(this.getRoomPosMgr().getPosList())) {
            // 玩家信息列表没数据
            return 0;
        }
        boolean isClubOrUnion = RoomTypeEnum.checkUnionOrClub(this.getRoomTypeEnum());
        List<Long> kickOutList = new ArrayList<>();
        if(isClubOrUnion){
            this.getRoomPosMgr().getPosList().stream().forEach(k -> {
                if ( k.getPid() <= 0L) {
                    return;
                }
                if( k.isLeaveNextSet()){
                    kickOutList.add(k.getPid());
                }
            });
        }
        return kickOutList.size();
    }
}
